package com.hd123.rumba.gwt.widget2.client.fielddef;

import java.util.Date;

import com.google.gwt.i18n.client.DateTimeFormat;
import com.hd123.rumba.gwt.util.client.RDateUtil;

/**
 * 日期类型字段的定义
 * 
 * @author LiQi
 * 
 */
@SuppressWarnings("deprecation")
public class DateFieldDef extends FieldDef {

  public static Date MIN_VALUE = new Date(1 - 1900, 0, 1);
  public static Date MAX_VALUE = new Date(9999 - 1900, 11, 31);

  /** 最小值，实际值应>=或>最小值（>=还是>由allowEqualsMin决定），为空则使用MIN_VALUE */
  protected Date minValue;

  /** 是否允许等于最小值 */
  protected boolean allowEqualsMin = true;

  /** 最大值，实际值应<=或<最大值（<=还是<由allowEqualsMax决定），为空则使用MAX_VALUE */
  protected Date maxValue;

  /** 是否允许等于最大值 */
  protected boolean allowEqualsMax = true;

  /** 日期时间的格式，用于从文本转换到日期时间 */
  protected DateTimeFormat format;

  /** 是否允许有时分秒的时间部分 */
  protected boolean hasTimePart = true;

  public DateFieldDef(String name, String caption) {
    super(name, caption, true);
  }

  public DateFieldDef(String name, String caption, boolean nullable, Date minValue,
      boolean allowEqualsMin, Date maxValue, boolean allowEqualsMax, DateTimeFormat format,
      boolean hasTimePart) {
    super(name, caption, nullable);
    this.minValue = minValue == null ? MIN_VALUE : minValue;
    this.allowEqualsMin = allowEqualsMin;
    this.maxValue = maxValue == null ? MAX_VALUE : maxValue;
    this.allowEqualsMax = allowEqualsMax;
    this.format = format;
    this.hasTimePart = hasTimePart;
  }

  public FieldDef clone() {
    return new DateFieldDef(name, caption, nullable, minValue, allowEqualsMin, maxValue,
        allowEqualsMax, format, hasTimePart);
  }

  public boolean validateText(String text, StringBuffer message) {
    return validateText(text, message, true);
  }

  public boolean validateText(String text, StringBuffer message, boolean checkNullable) {
    Date value;
    if (text == null || text.trim().equals(""))
      value = null;
    else {
      try {
        value = format.parse(text);
      } catch (IllegalArgumentException e) {
        finalizeMessage(message, "不是合法的日期格式");
        return false;
      }
    }

    return validate(value, message, checkNullable);
  }

  public boolean validate(Date value, StringBuffer message) {
    return validate(value, message, true);
  }

  /**
   * 验证传入的值是否合法
   * 
   * @param value
   * @return
   */
  public boolean validate(Date value, StringBuffer message, boolean checkNullable) {
    boolean result = super.validate(value, message, checkNullable);
    if (value == null)
      return result;

    // minValue
    if (minValue != null && (value.before(minValue) || (!allowEqualsMin && value.equals(minValue)))) {
      appendMessage(message, "应该大于" + (allowEqualsMin ? "等于" : "") + format.format(minValue));
      result = false;
    }

    // maxValue
    if (maxValue != null && (value.after(maxValue) || (!allowEqualsMax && value.equals(maxValue)))) {
      appendMessage(message, "应该小于" + (allowEqualsMax ? "等于" : "") + format.format(maxValue));
      result = false;
    }

    // hasTimePart
    if (!hasTimePart && RDateUtil.hasTimePart(value)) {
      appendMessage(message, "不允许有时分秒的时间部分");
      result = false;
    }

    finalizeMessage(message);
    return result;
  }

  public Date getMinValue() {
    return minValue;
  }

  public void setMinValue(Date minValue) {
    this.minValue = minValue;
  }

  public Date getMaxValue() {
    return maxValue;
  }

  public void setMaxValue(Date maxValue) {
    this.maxValue = maxValue;
  }

  public boolean isHasTimePart() {
    return hasTimePart;
  }

  public void setHasTimePart(boolean hasTimePart) {
    this.hasTimePart = hasTimePart;
  }

  public DateTimeFormat getFormat() {
    return format;
  }

  public void setFormat(DateTimeFormat format) {
    this.format = format;
  }

  public boolean isAllowEqualsMin() {
    return allowEqualsMin;
  }

  public void setAllowEqualsMin(boolean allowEqualsMin) {
    this.allowEqualsMin = allowEqualsMin;
  }

  public boolean isAllowEqualsMax() {
    return allowEqualsMax;
  }

  public void setAllowEqualsMax(boolean allowEqualsMax) {
    this.allowEqualsMax = allowEqualsMax;
  }

}
